package com.ryzx.security.filter;

import com.ryzx.auth.vo.BapUser;
import com.ryzx.common.util.JsonUtil;
import com.ryzx.common.util.RedisUtil;
import com.ryzx.common.util.TokenUtil;
import com.ryzx.security.entity.SecurityUserDetails;
import jakarta.servlet.FilterChain;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;


@Component
public class TokenLoginFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;

    public TokenLoginFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
        this.authenticationManager = authenticationManager;
        this.setPostOnly(false);
        this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/login","POST"));
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest req, HttpServletResponse res)
            throws AuthenticationException {
        try {
            StringBuilder sb = new StringBuilder();
            String line;

            BufferedReader br = new BufferedReader(new InputStreamReader(req.getInputStream()));
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            String str = sb.toString();

            HashMap<String,Object> hm = JsonUtil.String2HashMap(str);
            return authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(hm.get("account"), hm.get("ps"), new ArrayList<>()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Override
    protected void successfulAuthentication(HttpServletRequest req, HttpServletResponse res, FilterChain chain,
                                            Authentication auth) throws IOException {
        SecurityUserDetails user = (SecurityUserDetails) auth.getPrincipal();
        BapUser userinfo=user.getCurrentUserInfo();
        String account=user.getCurrentUserInfo().getAccount();
        Map<String,Object> hm=user.getAuthSet();
        hm.put("user",user.getCurrentUserInfo());
        String token = TokenUtil.createToken(account);
        RedisUtil.set(token,hm,1800);

        String sb = "{\"token\":\"" +
                token +
                "\",\"expire\":1800}";
        res.setContentType("text/html;charset=UTF-8");
        res.getWriter().write(sb);
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
                                              AuthenticationException e) {
        System.out.println(e.toString());
        System.out.println("login failed!");
    }
}

